home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1997 / HAM Radio 1997.iso / vcls / prtgrid / prtgrid.pas < prev    next >
Pascal/Delphi Source File  |  1996-04-08  |  19KB  |  838 lines

  1. unit Prtgrid;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils,  WinTypes,  WinProcs,  Messages,  Classes,  Graphics,  Controls, 
  7.     Forms,  Dialogs, DBGrids, DB
  8.     ;
  9.  
  10. const
  11.     MaxPages = 1000;
  12.     MaxCols = 100;
  13.  
  14.  
  15. type
  16.     TPageNumberPos = (pnNone,  pnTopLeft, pnTopCenter, pnTopRight, pnBotLeft, pnBotCenter, pnBotRight);
  17.  
  18.  
  19.   TPrintGrid = class(TComponent)
  20.   private
  21.     { Private declarations }
  22.         tmpFile: Text;
  23.         tmpFileName : TFileName;
  24.         FDBGrid: TDBGrid;
  25.         FHeaderInTitle: boolean;
  26.         FHeaderAlign: TAlignment;
  27.         FLinesFont: TFont;
  28.         FHeaderFont: TFont;
  29.         FTitleFont: TFont;
  30.         FPageNLabel: string;
  31.         FDateLabel: string;
  32.         FPageNPos: TPageNumberPos;
  33.         FDatePos: TPageNumberPos;
  34.         FPrintFileName: string;
  35.         FHeader: string;
  36.         FPrintMgrTitle: string;
  37.         FirstRecordY: longint;
  38.         LinesWidth: longint;
  39.         LinesHeight: longint;
  40.         RecCounter: longint;
  41.         FToPrint: boolean;
  42.         tmpPageNo: longint;
  43.         FFromPage: longint;
  44.         FToPage: longint;
  45.         NPositions: integer;
  46.         FTopMargin: integer;
  47.         FBottomMargin: integer;
  48.         FLeftMargin: integer;
  49.         FRightMargin: integer;
  50.         Positions: array[1..MaxCols] of longint;
  51.         FColLines: boolean;
  52.         FRowLines: boolean;
  53.         FBorder: boolean;
  54.         FHorizGap: integer;
  55.         FVertGap: integer;
  56.  
  57.         procedure WriteLineScreen(const S: string);
  58.         procedure SetTitleFont(Value: TFont);
  59.         procedure SetHeaderFont(Value: TFont);
  60.         procedure SetLinesFont(Value: TFont);
  61.         procedure SetDBGrid(Value: TDBGrid);
  62.         function GetDBGrid: TDBGrid;
  63.         procedure SetPrintMgrTitle(const S: string);
  64.         function GetPrintMgrTitle: string;
  65.         function OpenTextForWrite: boolean;
  66.         function ScreenWidth(tmp: TField): longint;
  67.         function TitleWidth(const S: string): longint;
  68.         function TitleHeight: longint;
  69.         procedure CalculatePositions;
  70.         function SetAlign(align:TAlignment; Left, Right: longint): longint;
  71.         function SetPagePosX(PagePos: TPageNumberPos; Left, Right: longint): longint;
  72.         function SetPagePosY(PagePos: TPageNumberPos; Top, Bottom: longint): longint;
  73.         function PrepareAlign(Field: TField; Col: integer): longint;
  74.         procedure WriteHeaderToPrinter;
  75.         procedure WriteHeader;
  76.         procedure WriteRecordToPrinter;
  77.         procedure WriteRecord;
  78.         procedure PageJump;
  79.         function RealWidth: longint;
  80.         function AllPageFilled: boolean;
  81.  
  82.   protected
  83.         { Protected declarations }
  84.     procedure SetName(const Value: TComponentName); override;
  85.  
  86.   public
  87.     { Public declarations }
  88.         constructor Create(AOwner:TComponent); override;
  89.         destructor Destroy; override;
  90.     procedure Print;
  91.     procedure PrintDialog;
  92.  
  93.     published
  94.         { Published declarations }
  95.         property LeftMargin: integer read FLeftMargin write FLeftMargin;
  96.         property TopMargin: integer read FTopMargin write FTopMargin;
  97.         property RightMargin: integer read FRightMargin write FRightMargin;
  98.         property BottomMargin: integer read FBottomMargin write FBottomMargin;
  99.         property TitleFont: TFont read FTitleFont write SetTitleFont;
  100.         property HeaderFont: TFont read FHeaderFont write SetHeaderFont;
  101.         property LinesFont: TFont read FLinesFont write SetLinesFont;
  102.         property DBGrid: TDBGrid read GetDBGrid write SetDBGrid;
  103.         property PrintMgrTitle: string read GetPrintMgrTitle write SetPrintMgrTitle;
  104. {        property HeaderInTitle: boolean read FHeaderInTitle write FHeaderinTitle;}{cannot get this to work properly}
  105.         property Header: string read FHeader write FHeader;
  106.         property HeaderAlignment: TAlignment read FHeaderAlign write FHeaderAlign;
  107.         property PrintToFile: boolean read FToPrint write FToPrint;
  108.         property PrintFileName: string read FPrintFileName write FPrintFileName;
  109.         property FromPage: longint read FFromPage write FFromPage;
  110.     property ToPage: longint read FToPage write FToPage;
  111.         property Border: boolean read FBorder write FBorder;
  112.         property ColLines: boolean read FColLines write FColLines;
  113.         property RowLines: boolean read FRowLines write FRowLines;
  114.         property HorizontalGap: integer read FHorizGap write FHorizGap;
  115.         property VerticalGapPct: integer read FVertGap write FVertGap;
  116.         property PageNumberPos: TPageNumberPos read FPageNPos write FPageNPos;
  117.         property PageNumberLabel: string read FPageNLabel write FPageNLabel;
  118.         property DatePos: TPageNumberPos read FDatePos write FDatePos;
  119.         property DateLabel: string read FDateLabel write FDateLabel;
  120.     end;
  121.  
  122. procedure Register;
  123.  
  124.  
  125. implementation
  126.  
  127. uses
  128.     Printers;
  129.  
  130.  
  131. function Max(a, b: longint): longint;
  132. begin
  133.     if a > b then
  134.         Result := a
  135.     else
  136.         Result := b;
  137. end;
  138.  
  139.  
  140. function FileNameExists(FileName: string): boolean;    { Check whether file exists and return true if it does }
  141. var
  142.     F: File;
  143. begin
  144.   Assign(F, FileName);
  145.     {$I-} Reset(F); {$I+}
  146.  
  147.     if IoResult <> 0 then
  148.         begin
  149.             FileNameExists := false;                                      { i.e. file information is in memory }
  150.         end
  151.     else
  152.         begin
  153.             Close(F);                                                            { Note: File does NOT remain open }
  154.             FileNameExists := true;                                          { i.e. file information is in memory }
  155.         end;
  156.  
  157. end;
  158.  
  159.  
  160. function Scale(Value: longint; Pct: integer): longint;
  161. begin
  162.     if Pct > 100 then
  163.         Pct := 100
  164.     else if Pct < 0 then
  165.         Pct := 0;
  166.  
  167.     if Pct = 0 then
  168.         Result := Value
  169.     else
  170.         Result := Value + MulDiv(Value, Pct, 100);
  171. end;
  172.  
  173.  
  174. function CenterY(PosY, TextHt, Pct: longint): longint;
  175. begin
  176.     Result := PosY + (Scale(TextHt, Pct) - TextHt) div 2;
  177. end;
  178.  
  179.  
  180.  
  181. constructor TPrintGrid.Create(AOwner:TComponent);
  182. begin
  183.     inherited Create(AOwner);
  184.     FTitleFont := TFont.Create;
  185.     FHeaderFont := TFont.Create;
  186.     FLinesFont := TFont.Create;
  187.  
  188.     { DEFAULT VALUES FOR ALL PROPERTIES }
  189.     FDBGrid := nil;
  190.   FHeader := '';
  191.   FPrintMgrTitle := '';
  192.   RecCounter := 0;
  193.   FHorizGap := 2;
  194.     FVertGap := 20;
  195.     FTopMargin := 40;
  196.     FBottomMargin := 40;
  197.     FLeftMargin := 30;
  198.     FRightMargin := 30;
  199.     FToPrint := False;
  200.     FPrintFileName := '';
  201.   FFromPage := 1;
  202.   FToPage := MaxPages;
  203.     FBorder := True;
  204.     FColLines := True;
  205.     FRowLines := False;
  206.   FHeaderAlign := taCenter;
  207.   FHeaderIntitle := False;
  208.     FPageNPos := pnTopRight;
  209.     FPageNLabel := 'Page: ';
  210.     FDatePos := pnTopLeft;
  211.     FDateLabel := '';
  212. end;
  213.  
  214.  
  215. destructor TPrintGrid.Destroy;
  216. begin
  217.     FTitleFont.Free;
  218.     FHeaderFont.Free;
  219.   FLinesFont.Free;
  220.     inherited Destroy;
  221. end;
  222.  
  223.  
  224. procedure TPrintGrid.SetTitleFont(Value: TFont);
  225. begin
  226.     FTitleFont.Assign(Value);
  227. end;
  228.  
  229.  
  230. procedure TPrintGrid.SetHeaderFont(Value: TFont);
  231. begin
  232.     FHeaderFont.Assign(Value);
  233. end;
  234.  
  235.  
  236. procedure TPrintGrid.SetLinesFont(Value: TFont);
  237. begin
  238.     FLinesFont.Assign(Value);
  239. end;
  240.  
  241.  
  242. procedure TPrintGrid.SetDBGrid(Value: TDBGrid);
  243. begin
  244.     FDBGrid := Value;
  245. end;
  246.  
  247.  
  248. function TPrintGrid.GetDBGrid: TDBGrid;
  249. begin
  250.     Result := FDBGrid;
  251. end;
  252.  
  253.  
  254. procedure TPrintGrid.SetPrintMgrTitle(const S: string);
  255. begin
  256.     FPrintMgrTitle := S;
  257. end;
  258.  
  259.  
  260. function TPrintGrid.GetPrintMgrTitle: string;
  261. begin
  262.     Result := FPrintMgrTitle;
  263. end;
  264.  
  265.  
  266. procedure TPrintGrid.SetName(const Value: TComponentName);
  267. var
  268.   ChangeText: Boolean;
  269. begin
  270.     ChangeText := (Name = FPrintMgrTitle) and ((Owner = nil) or not (Owner is TPrintGrid) or
  271.                                     not (csLoading in TPrintGrid(Owner).ComponentState));
  272.  
  273.     inherited SetName(Value);
  274.  
  275.     if ChangeText then
  276.         FPrintMgrTitle := Value;
  277. end;
  278.  
  279.  
  280. procedure TPrintGrid.WriteLineScreen(const S: string);
  281. begin
  282.     if (tmpPageNo >= FFromPage) and (tmpPageNo <= FToPage) then
  283.         Writeln(tmpFile, S);
  284. end;
  285.  
  286.  
  287. function TPrintGrid.OpenTextForWrite: boolean;
  288. begin
  289.     if tmpFileName <> '' then
  290.         begin
  291.          {$I-}
  292.             AssignFile(tmpFile, tmpFileName);
  293.             rewrite(tmpFile);
  294.             {$I+}
  295.             Result := (ioresult = 0);
  296.         end
  297.  
  298.     else
  299.         Result := false;
  300. end;
  301.  
  302.  
  303. function TPrintGrid.ScreenWidth(tmp:TField): longint;
  304. begin
  305.     Result := Max(tmp.DisplayWidth, Length(tmp.DisplayLabel));
  306. end;
  307.  
  308.  
  309. function TPrintGrid.TitleWidth(const S: string): longint;
  310. var
  311.     tmpFont: TFont;
  312. begin
  313.     with Printer.Canvas do
  314.     begin
  315.         tmpFont := TFont.Create;
  316.         tmpFont.Assign(Font);
  317.         Font.Assign(FTitleFont);
  318.         Result := TextWidth(s);
  319.         Font.Assign(tmpFont);
  320.         tmpFont.Free;
  321.     end;
  322. end;
  323.  
  324.  
  325. function TPrintGrid.TitleHeight: longint;
  326. var
  327.     tmpFont: TFont;
  328. begin
  329.     with Printer.Canvas do
  330.     begin
  331.         tmpFont := TFont.Create;
  332.         tmpFont.Assign(Font);
  333.         Font.Assign(FTitleFont);
  334.         Result := Scale(TextHeight('M'), FVertGap);
  335.         Font.Assign(tmpFont);
  336.         tmpFont.Free;
  337.     end;
  338. end;
  339.  
  340.  
  341. procedure TPrintGrid.CalculatePositions;
  342. var longitud, t: longint;
  343. begin
  344.     NPositions := 0;
  345.  
  346.     if FBorder then
  347.         Positions[1] := 1
  348.     else
  349.         Positions[1] := 0;
  350.  
  351.     with FDBGrid.DataSource.DataSet do
  352.  
  353.         for t := 0 to FieldCount - 1 do
  354.         with Fields[t] do
  355.  
  356.         if Visible then
  357.         begin
  358.             inc(NPositions);
  359.             longitud := Max(TitleWidth(Fields[t].DisplayLabel), (LinesWidth * Fields[t].DisplayWidth));
  360.             Positions[NPositions + 1] := Positions[NPositions] + Longitud + FHorizGap;
  361.         end;
  362. end;
  363.  
  364.  
  365. function TPrintGrid.SetAlign(align: TAlignment; Left, Right: longint): longint;
  366. var
  367.     PosX: longint;
  368. begin
  369.     with Printer.Canvas do
  370.     begin
  371.         case Align of
  372.             taLeftJustify:
  373.                 begin
  374.                     SetTextAlign(Handle, TA_LEFT);
  375.                     PosX := Left + FHorizGap;
  376.                 end;
  377.  
  378.             taRightJustify:
  379.                 begin
  380.                     SetTextAlign(Handle, TA_RIGHT);
  381.                     PosX := Right - FHorizGap;
  382.                 end;
  383.  
  384.             taCenter:
  385.                 begin
  386.                     SetTextAlign(Handle, TA_CENTER);
  387.                     PosX := Left + Round((Right - Left) / 2);
  388.                 end;
  389.         end;
  390.     end;
  391.  
  392.     Result := PosX;
  393. end;
  394.  
  395.  
  396. function TPrintGrid.SetPagePosX(PagePos: TPageNumberPos; Left, Right: longint): longint;
  397. var
  398.     PosX: longint;
  399. begin
  400.     with Printer.Canvas do
  401.     begin
  402.         case PagePos of
  403.             pnTopLeft, pnBotLeft:
  404.                 begin
  405.                     SetTextAlign(Handle, TA_LEFT);
  406.                     PosX := Left + FHorizGap;
  407.                 end;
  408.  
  409.             pnTopRight, pnBotRight:
  410.                 begin
  411.                     SetTextAlign(Handle, TA_RIGHT);
  412.                     PosX := Right - FHorizGap;
  413.                 end;
  414.  
  415.             pnTopCenter, pnBotCenter:
  416.                 begin
  417.                     SetTextAlign(Handle, TA_CENTER);
  418.                     PosX := Left + Round((Right - Left)/2);
  419.                 end;
  420.         end;
  421.     end;
  422.  
  423.     Result := PosX;
  424. end;
  425.  
  426.  
  427. function TPrintGrid.SetPagePosY(PagePos: TPageNumberPos; Top, Bottom: longint): longint;
  428. var
  429.     PosY: longint;
  430. begin
  431.         case PagePos of
  432.             pnBotLeft, pnBotCenter, pnBotRight:
  433.                 begin
  434.                     PosY := Bottom;
  435.                 end;
  436.  
  437.         else
  438.             PosY := Top;
  439.         end;
  440.  
  441.     Result := PosY;
  442. end;
  443.  
  444.  
  445. function TPrintGrid.PrepareAlign(Field:TField; Col:integer): longint;
  446. begin
  447.     Result := SetAlign(Field.Alignment, Positions[col], Positions[col + 1]);
  448. end;
  449.  
  450.  
  451. procedure TPrintGrid.WriteHeaderToPrinter;
  452. var
  453.     col, PosX, PosY, t, tmpTitleHeight: longint;
  454.     s: string;
  455.     TmpFont: TFont;
  456.     FontCreated: boolean;
  457. begin
  458.     if (tmpPageNo >= FFromPage) and (tmpPageNo <= FToPage) then
  459.     begin
  460.         tmpTitleHeight := TitleHeight;
  461.  
  462.         with Printer.Canvas do
  463.         begin
  464.             if (FHeader <> '') or (FDatePos <> pnNone) or (FPageNPos <> pnNone) then
  465.                 begin
  466.                     tmpFont := TFont.Create;
  467.                     tmpFont.Assign(Font);
  468.                     Font.Assign(FHeaderFont);
  469.                     FontCreated := true;
  470.                 end
  471.             else
  472.                 FontCreated := false;
  473.  
  474.             if FDatePos <> pnNone then
  475.             begin
  476.                 PosX := SetPagePosX(FDatePos, FLeftMargin, FLeftMargin + Positions[NPositions + 1]);
  477.                 PosY := SetPagePosY(FDatePos, FTopMargin, Printer.PageHeight - FBottomMargin);
  478.                 TextOut(PosX, PosY, FDateLabel);
  479.             end;
  480.  
  481.             if FHeader <> '' then
  482.             begin
  483.                 PosX := SetAlign(FHeaderAlign, FLeftMargin, FLeftMargin + Positions[NPositions + 1]);
  484.                 TextOut(PosX, FTopMargin, FHeader);
  485.             end;
  486.  
  487.             if FPageNPos <> pnNone then
  488.             begin
  489.                 PosX := SetPagePosX(FPageNPos, FLeftMargin, FLeftMargin + Positions[NPositions + 1]);
  490.                 PosY := SetPagePosY(FPageNPos, FTopMargin, Printer.PageHeight - FBottomMargin);
  491.                 TextOut(PosX, PosY, FPageNLabel + IntToStr(tmpPageNo));
  492.             end;
  493.  
  494.             if (FHeader <> '') or (FDatePos in [pnTopLeft, pnTopCenter, pnTopRight])
  495.                                                  or (FPageNPos in [pnTopLeft, pnTopCenter, pnTopRight]) then
  496.                 FirstRecordY := FTopMargin + Scale(TextHeight('M'), FVertGap) + tmpTitleHeight
  497.             else
  498.                 FirstRecordY := FTopMargin + tmpTitleHeight;
  499.  
  500.             if FontCreated then
  501.             begin
  502.                 Font.Assign(tmpFont);
  503.                 tmpFont.Free;
  504.             end;
  505.         end;
  506.  
  507.         if FBorder then
  508.         begin
  509.             if FHeaderinTitle then
  510.                 Printer.Canvas.Rectangle(FLeftMargin, FTopMargin, FLeftMargin + Positions[NPositions + 1],
  511.                                                                  Printer.PageHeight - FBottomMargin)
  512.             else
  513.                 Printer.Canvas.Rectangle(FLeftMargin, FirstRecordY - tmpTitleHeight, FLeftMargin + Positions[NPositions + 1],
  514.                                                                  Printer.PageHeight - FBottomMargin)
  515.         end;
  516.  
  517.         if FColLines then
  518.             with Printer.Canvas do
  519.             for t := 2 to NPositions do
  520.             begin
  521.                 MoveTo(FLeftMargin + Positions[t], FirstRecordY);
  522.                 LineTo(FLeftMargin + Positions[t], Printer.PageHeight - FBottomMargin);
  523.             end;
  524.  
  525.         col := 0;
  526.  
  527.         with FDBGrid.DataSource.DataSet do
  528.         with Printer.Canvas do
  529.         begin
  530.             tmpFont := TFont.Create;
  531.             tmpFont.Assign(Font);
  532.             Font.Assign(FTitleFont);
  533.  
  534.             for t := 0 to FieldCount - 1 do
  535.                 with Fields[t] do
  536.  
  537.                 if Visible then
  538.                 begin
  539.                     inc(Col);
  540.                     PosX := PrepareAlign(Fields[t], Col);
  541.                     PosY := CenterY(FirstRecordY - tmpTitleHeight, TextHeight('M'), FVertGap);
  542.                     TextOut(FLeftMargin + PosX, PosY, DisplayLabel);
  543.                 end;
  544.  
  545.             Moveto(FLeftMargin, FirstRecordY);
  546.             Lineto(FLeftMargin + Positions[NPositions + 1], FirstRecordY);
  547.             Font.Assign(tmpFont);
  548.             tmpFont.Free;
  549.         end;
  550.     end;
  551. end;
  552.  
  553.  
  554. procedure TPrintGrid.WriteHeader;
  555. var
  556.     t: longint;
  557.     S: string;
  558. begin
  559.     if not FToPrint then
  560.         WriteHeaderToPrinter
  561.  
  562.     else
  563.         with FDBGrid.DataSource.DataSet do
  564.         begin
  565.       WriteLineScreen(FHeader);
  566.             S := '';
  567.  
  568.       for t := 0 to FieldCount - 1 do
  569.             begin
  570.                 if Fields[t].Visible then
  571.                     S := S + Fields[t].DisplayLabel + #9;
  572.             end;
  573.  
  574.             WriteLineScreen(S);
  575.         end;
  576. end;
  577.  
  578.  
  579. procedure TPrintGrid.WriteRecordToPrinter;
  580. var
  581.     Col, t, PosX, PosY: longint;
  582.     tmpFont: TFont;
  583. begin
  584.     if (tmpPageNo >= FFromPage) and (tmpPageNo <= FToPage) then
  585.     begin
  586.         with FDBGrid.DataSource.DataSet do
  587.         begin
  588.             Col := 0;
  589.             PosY := FirstRecordY + RecCounter * LinesHeight;
  590.  
  591.             for t := 0 to FieldCount - 1 do
  592.             with Fields[t] do
  593.             if Visible then
  594.                 with Printer.Canvas do
  595.                 begin
  596.                     tmpFont := TFont.Create;
  597.                     tmpFont.Assign(Font);
  598.                     Font.Assign(FLinesFont);
  599.                     inc(Col);
  600.                     PosX := PrepareAlign(Fields[t], Col);
  601.                     TextOut(FLeftMargin + PosX, CenterY(PosY, TextHeight('M'), FVertGap), DisplayText);
  602.                     Font.Assign(tmpFont);
  603.                     tmpFont.Free;
  604.                 end;
  605.  
  606.             if FRowLines then
  607.             with Printer.Canvas do
  608.             begin
  609.                 MoveTo(FLeftMargin, PosY);
  610.                 LineTo(FLeftMargin + Positions[NPositions + 1], PosY);
  611.             end;
  612.         end;
  613.     end;
  614. end;
  615.  
  616.  
  617. procedure TPrintGrid.WriteRecord;
  618. var
  619.     t: word;
  620.     S: string;
  621. begin
  622.     if not FToPrint then
  623.         WriteRecordToPrinter
  624.  
  625.     else
  626.         begin
  627.             with FDBGrid.DataSource.DataSet do
  628.             begin
  629.                 S := '';
  630.  
  631.                 for t := 0 to FieldCount - 1 do
  632.                 begin
  633.                     if Fields[t].Visible then
  634.                         S := S + Fields[t].DisplayText + #9;
  635.                 end;
  636.             end;
  637.  
  638.             WriteLineScreen(S);
  639.         end;
  640. end;
  641.  
  642.  
  643. procedure TPrintGrid.PageJump;
  644. begin
  645.     RecCounter := 0;
  646.  
  647.     if not FToPrint then
  648.         if (tmpPageNo >= FFromPage) and (tmpPageNo < FToPage) then
  649.             Printer.NewPage;
  650.  
  651.     inc(tmpPageNo);
  652. end;
  653.  
  654.  
  655. function TPrintGrid.RealWidth: longint;
  656. begin
  657.     Result := Printer.PageWidth - FLeftMargin - FRightMargin;
  658. end;
  659.  
  660.  
  661. function TPrintGrid.AllPageFilled: boolean;
  662. begin
  663.     Result := (FToPrint and (RecCounter=66)) or
  664.                         (not FToPrint and
  665.                         ((FirstRecordY + (RecCounter - 1) * LinesHeight) >= (Printer.PageHeight - FBottomMargin)));
  666. end;
  667.  
  668.  
  669. procedure TPrintGrid.Print;
  670. var
  671.     res: boolean;
  672.     St: array[0..255] of Char;
  673.     BookMark: TBookMark;
  674.     t: integer;
  675.     tmpFont: TFont;
  676. begin
  677.     if not Assigned(FDBGrid) then
  678.         raise Exception.Create('PrintGrid. DBGrid Property Was Not Specified.');
  679.  
  680.     if FToPrint then
  681.         res := OpenTextForWrite
  682.  
  683.   else
  684.         begin
  685.             res := true;
  686.  
  687.             with Printer do
  688.             begin
  689.                 Title := FPrintMgrTitle;
  690.                 BeginDoc;
  691.  
  692.                 with Canvas do
  693.                 begin
  694.                     tmpFont := TFont.Create;
  695.                     tmpFont.Assign(Font);
  696.                     Font.Assign(FLinesFont);
  697.                     LinesHeight := Scale(TextHeight('M'), FVertGap);
  698.                     LinesWidth := TextWidth('0');
  699.                     Font.Assign(tmpFont);
  700.                     tmpFont.Free;
  701.                 end;
  702.             end;
  703.     end;
  704.  
  705.     if res then
  706.   begin
  707.     with FDBGrid.DataSource.DataSet do
  708.     try
  709.             Screen.Cursor := crHourGlass;
  710.             Bookmark := GetBookMark;
  711.       DisableControls;
  712.       First;
  713.       RecCounter := 0;
  714.       tmpPageNo := 1;
  715.             CalculatePositions; { where to place each field in horizontal plane? }
  716.  
  717.             if not FToPrint and (Positions[NPositions + 1] > RealWidth) then
  718.             begin
  719.                 Screen.Cursor := crDefault;
  720.                 ShowMessage('Report Width Is Greater Than Paper Width.'); { useful in design }
  721.                 Screen.Cursor := crHourGlass;
  722.             end;
  723.  
  724.             while not EOF do
  725.       begin
  726.                 if RecCounter = 0 then
  727.                     WriteHeader;
  728.  
  729.                 WriteRecord;
  730.                 Inc(RecCounter);
  731.                 next;
  732.  
  733.                 if AllPageFilled then
  734.         begin
  735.           PageJump;
  736.  
  737.                     if tmpPageNo > FToPage then
  738.                         break;
  739.         end;
  740.             end;
  741.  
  742.     finally
  743.             Screen.Cursor := crDefault;
  744.             GotoBookMark(BookMark);
  745.       EnableControls;
  746.             FreeBookMark(BookMark);
  747.  
  748.             if FToPrint then
  749.                 System.closefile(tmpFile)
  750.             else
  751.                 Printer.EndDoc;
  752.     end;
  753.     end
  754.  
  755.     else
  756.         raise Exception.Create('Error Creating Report.');
  757. end;
  758.  
  759.  
  760. procedure TPrintGrid.PrintDialog;
  761. var
  762.     M: integer;
  763. begin
  764.     with TPrintDialog.Create(Self) do
  765.     begin
  766.         try
  767.             Options := [poPageNums, poPrintToFile, poWarning];    {poHelp}
  768.             MinPage := 1;
  769.             MaxPage := MaxPages;
  770.             FFromPage := 1;
  771.             FToPage := MaxPages;
  772.  
  773.             if Execute then
  774.             begin
  775.                 if PrintRange = prPageNums then
  776.                 begin
  777.                     FFromPage := FromPage;
  778.                     FToPage := ToPage;
  779.                 end;
  780.  
  781.                 if not PrintToFile then
  782.                     begin
  783.                         FToPrint := false;
  784.                         Print;
  785.                     end
  786.                 else
  787.                     begin
  788.                         FToPrint := true;
  789.  
  790.                         with TSaveDialog.Create(Self) do
  791.                         begin
  792.                             try
  793.                                 Filter := 'Text files (*.TXT)|*.TXT|Any file (*.*)|*.*';
  794.  
  795.                                 if FPrintFileName <> '' then
  796.                                 begin
  797.                                     FileName := FPrintFileName;
  798.                                     Filter := Filter + '|This file (*' + ExtractFileExt(FileName) + ')|*' + ExtractFileExt(FileName);
  799.                                     FilterIndex := 3;
  800.                                 end;
  801.  
  802.                                 if Execute then
  803.                                 begin
  804.                                     M := mrYes;
  805.  
  806.                                     if FileNameExists(FileName) then
  807.                                         M := MessageDlg(FileName + ' Already Exists. Do You Want To Overwrite This File?',
  808.                                                                         mtConfirmation, [mbYes, mbNo], 0);
  809.  
  810.                                     if M = mrYes then
  811.                                     begin
  812.                                         tmpFileName := FileName;
  813.                                         Print;
  814.                                     end;
  815.                                 end;
  816.  
  817.                             finally
  818.                                 Free;
  819.                             end;
  820.                         end;
  821.                     end;
  822.             end;
  823.  
  824.         finally
  825.             Free;
  826.         end;
  827.     end;
  828. end;
  829.  
  830.  
  831. procedure Register;
  832. begin
  833.     RegisterComponents('Data Controls', [TPrintGrid]);
  834. end;
  835.  
  836.  
  837. end.
  838.